<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>

        /**
         * Object.defineProperty（对象，属性名，参数对象）
         * 使用场景：
         * 数据代理(通过一个变量来访问两外一个变量里的值，方便操作，例如我想通过objA去访问objB.C.D的值)，
         * 响应式对象（数据双向绑定），将某个对象的值和某个变量进行绑定
        */
        
       
        /**
         * 注意点：
         * 浏览器识别属性：
         * 1.低亮:不可枚举
         * 2.三个点（...）：有getter
         * 3.高亮：可枚举
         * value和getter只能选一个
         * writable和setter只能选一个
         * 
         * */

        
            //场景1：双向绑定age和obj1.age，这样age和obj1.age两个的值共享
            let age=10;
            let obj1={
                name:'kevin', // 浏览器里会高亮
            }
            // 
            Object.defineProperty(obj1,'age',{
                // value:999, // 属性值,有getter就不能声明这个属性
                enumerable:true, // 是否可枚举,否的话属性会低亮
               // writable:true, // 是否可写入,有setter就不能声明这个属性
                configurable:true, // 是否可删除
                get(){
                    return age;
                },
                set(val){
                    age=val;
                }
            }
            )
            
       
            // 这样是无法进行数据绑定
            // let obj1={age:10};
            // let obj2={name:'kevin',age:obj1.age}
            
       
            /**
             * vue是如何通过defineProperty实现数据双向绑定？
             * vue是通过defineProperty的setter和getter实现双向绑定的
             * vue实例把data保存到_data属性(_data对data进行数据劫持，就是用observer来实现)
             * 然后通过循环里面的所有属性进行defineProperty然后设置setter和getter
             * 
            */
      
            
            
            
            
             // defineProperties可以一次性写多个属性   
            // Object.defineProperties(obj, {
            //     'property1': {
            //         value: true,
            //         writable: true
            //     },
            //     'property2': {
            //         value: 'Hello',
            //         writable: false
            //     }
            //     // etc. etc.
            //     });
    </script>
</body>
</html>